#include "TcpConnection.h"
#include "TcpServer.h"
#include <iostream>
#include <unistd.h>

using std::cout;
using std::endl;

class MyTask
{
public:
    MyTask(const string &msg, const TcpConnectionPtr &con)
    : _msg(msg)
    , _con(con)
    {

    }
    void process()
    {
        _msg;
        //msg就可以在MyTask的process进行处理
        //在该函数中，处理业务逻辑，也就是msg
        //执行decode、compute、encode
        //执行的过程全部在该函数中
        //
        //数据的发送与接收是同一个对象，也就是Reactor/EventLoop，需要进行
        //read/send操作,线程池需要处理业务逻辑,当线程池处理好业务逻辑之后
        //需要将消息发送给EventLoop
        //线程池这种线程使用来处理业务逻辑的，也就是进行计算的。
        //而eventLoop/Reactor是进行read/write操作的，也即是IO操作。
        //将线程池称为计算线程，将EventLoop称为IO线程。
        //线程计算线程将数据处理完毕之后，需要将数据传递给IO线程
        //就会涉及到线程之间的通信问题？
        //问题就转接为线程之间如何进行通信？(eventfd)
        //eventfd就可以处理线程之间的通信
        //msg1;//新的msg1
        _con->sendInLoop(_msg);
        //由TcpConnection将数据发送给EventLoop
        //所以TcpConnection必须要知道EventLoop的存在
    }
private:
    string _msg;
    TcpConnectionPtr _con;

};

//TCP网编编程中的三个事件（从类外传递进来）
void onConnection(const TcpConnectionPtr &con)
{
    cout << con->toString() << " has connected!" << endl;
}

void onMessage(const TcpConnectionPtr &con)
{
    //接收客户端发送过来的数据
    string msg = con->receive();
    //如果在此处就处理msg，也就是进行deconde、compute、encode
    //如果这三个操作，也就是业务逻辑的处理，比较耗时的话，
    //那么处理业务逻辑就成为了该版本的瓶颈
    //所以为了解决业务逻辑耗时比较长的问题，就需要将业务逻辑
    //的处理放在线程池中
    
    MyTask task(msg, con);

    pool.addTask(std::bind(&MyTask::process, task));

    /* cout << "recv from client " << msg << endl; */
    //将从客户端发送过来的数据传回给客户端
    /* con->send(msg); */
}

void onClose(const TcpConnectionPtr &con)
{
    cout << con->toString() << " has closed!" << endl;
}

void test()
{
    TcpServer server("127.0.0.1", 8888);
    server.setAllCallback(std::move(onConnection),
                          std::move(onMessage)
                          , std::move(onClose));
    server.start();

}

int main(int argc, char **argv)
{
    test();
    return 0;
}

